package com.yida.gwj.common.aspect;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.yida.common.core.utils.SpelUtils;
import com.yida.gwj.common.domain.GwjMqMessageLog;
import com.yida.gwj.common.domain.mq.MqMessageBody;
import com.yida.gwj.common.domain.mq.MqSendRequest;
import com.yida.gwj.common.domain.mq.MqSendResult;
import com.yida.gwj.common.service.IGwjMqMessageLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Optional;

/**
 * Mq消息处理
 *
 * @author liangp
 * @date 2023/03/02
 */
@Component
@Aspect
public class MqMessageLogAspect {

    private final Logger log = LoggerFactory.getLogger(MqMessageLogAspect.class);

    private final String topicStr = "topic";
    private final String tagStr = "tag";
    private final String keyStr = "key";
    private final String levelStr = "level";
    private final String serverIdentificationStr = "serverIdentification";

    @Autowired
    private IGwjMqMessageLogService mqMessageLogService;

    @Pointcut("execution(* com.yida.gwj.common.handler.MqSendMessageHandler.*(..)) ")
    public void pointCut() {
    }

    @AfterReturning(value = "pointCut()", returning = "mqSendResult")
    public void afterReturning(JoinPoint joinPoint, MqSendResult mqSendResult) {
        log.info("MQ消费信息发送日志处理 -> 请求参数 [{}],响应参数 [{}]", joinPoint, mqSendResult);
        if (ObjectUtil.isNull(joinPoint.getArgs())) {
            return;
        }
        GwjMqMessageLog mqMessageLog = new GwjMqMessageLog();
        mqMessageLog.setSendTime(LocalDateTime.now());
        mqMessageLog.setStatus(mqSendResult.isSuccess());
        try {
            // 设置方法名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            mqMessageLog.setMethod(className + "." + methodName + "()");

            for (Object object : joinPoint.getArgs()) {
                if (object instanceof MqMessageBody) {
                    StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(object);
                    standardEvaluationContext = SpelUtils.setContextVariables(standardEvaluationContext, joinPoint);
                    Optional<String> serverIdentification = SpelUtils.getElValue(String.class, serverIdentificationStr, standardEvaluationContext);
                    if (!serverIdentification.isPresent()) {
                        return;
                    }
                    mqMessageLog.setServerIdentification(serverIdentification.get());
                    mqMessageLog.setContent(JSONUtil.toJsonStr(object));
                }
                if (object instanceof MqSendRequest) {
                    StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(object);
                    standardEvaluationContext = SpelUtils.setContextVariables(standardEvaluationContext, joinPoint);
                    Optional<String> topic = SpelUtils.getElValue(String.class, topicStr, standardEvaluationContext);
                    if (!topic.isPresent()) {
                        return;
                    }
                    Optional<String> tag = SpelUtils.getElValue(String.class, tagStr, standardEvaluationContext);
                    if (!tag.isPresent()) {
                        return;
                    }
                    Optional<String> key = SpelUtils.getElValue(String.class, keyStr, standardEvaluationContext);
                    if (!key.isPresent()) {
                        return;
                    }
                    Optional<Integer> level = SpelUtils.getElValue(Integer.class, levelStr, standardEvaluationContext);
                    if (!level.isPresent()) {
                        return;
                    }

                    mqMessageLog.setMessageTopic(topic.get());
                    mqMessageLog.setMessageTag(tag.get());
                    mqMessageLog.setMessageKey(key.get());
                    mqMessageLog.setMessageLevel(level.get());
                }
            }
            mqMessageLogService.insertGwjMqMessageLog(mqMessageLog);
        } catch (Exception e) {
            log.info("MQ消费信息发送日志处理 -> [{}]", e);
            return;
        }
    }

}
